/**
 * @file scd4x.h
 * @brief SCD4X CO2 sensor driver for ESP32 IDF
 * @details Combined implementation with I2C communication handling
 * @author CodeBuddy
 * @version 1.1
 * @date 2025-09-12
 */

#pragma once

#include "i2c_device.h"
#include <driver/i2c.h>
#include <esp_log.h>
#include <stdint.h>
#include <string>
#include <vector>
#include "esp_timer.h"

// SCD4X I2C address
#define SCD4X_I2C_ADDR 0x62

// SCD4X Commands
#define SCD4X_START_PERIODIC_MEASURE    0x21B1
#define SCD4X_READ_MEASUREMENT          0xEC05
#define SCD4X_STOP_PERIODIC_MEASURE     0x3F86
#define SCD4X_SET_TEMPERATURE_OFFSET    0x241D
#define SCD4X_GET_TEMPERATURE_OFFSET    0x2318
#define SCD4X_SET_SENSOR_ALTITUDE       0x2427
#define SCD4X_GET_SENSOR_ALTITUDE       0x2322
#define SCD4X_SET_AMBIENT_PRESSURE      0xE000
#define SCD4X_PERFORM_FORCED_RECALIB    0x362F
#define SCD4X_SET_AUTOMATIC_CALIB       0x2416
#define SCD4X_GET_AUTOMATIC_CALIB       0x2313
#define SCD4X_START_LOW_POWER_MEASURE   0x21AC
#define SCD4X_GET_DATA_READY_STATUS     0xE4B8
#define SCD4X_PERSIST_SETTINGS          0x3615
#define SCD4X_GET_SERIAL_NUMBER         0x3682
#define SCD4X_PERFORM_SELF_TEST         0x3639
#define SCD4X_PERFORM_FACTORY_RESET     0x3632
#define SCD4X_REINIT                    0x3646
#define SCD4X_MEASURE_SINGLE_SHOT       0x219D
#define SCD4X_MEASURE_SINGLE_SHOT_RHT_ONLY 0x2196
#define SCD4X_POWER_DOWN                0x36E0
#define SCD4X_WAKE_UP                   0x36F6

// Measurement modes
#define SCD4X_MODE_STOP                 0
#define SCD4X_MODE_PERIODIC             1
#define SCD4X_MODE_LOW_POWER            2

class SCD4X : public I2cDevice {
public:
    typedef struct {
        uint16_t co2_ppm;
        float temperature;
        float humidity;
    } Measurement;

    SCD4X(i2c_master_bus_handle_t i2c_bus, uint8_t addr = SCD4X_I2C_ADDR);
    bool begin();
    void setSleepMode(bool sleep);
    uint16_t performSelfTest();
    void moduleReinit();
    void performFactoryReset();
    void measureSingleShot(bool rht_only = false);
    void enablePeriodMeasure(uint8_t mode);
    bool readMeasurement(Measurement* data);
    bool getDataReadyStatus();
    void setTempComp(float temp_comp);
    float getTempComp();
    void setSensorAltitude(uint16_t altitude);
    uint16_t getSensorAltitude();
    void setAmbientPressure(uint32_t ambient_pressure);
    void setAutoCalibMode(bool enable);
    bool getAutoCalibMode();
    void persistSettings();
    bool getSerialNumber(uint16_t serial[3]);
    int16_t performForcedRecalibration(uint16_t co2_ppm);
    #if 0
    // 简化的数据记录功能 - 只使用一个文件目录
    bool SaveCurrentData();  // 保存当前数据到预定义文件
    bool StartTimedLogging(int interval_seconds);  // 启动定时记录
    void StopTimedLogging();  // 停止定时记录
    bool IsTimedLogging() const { return is_logging_; }  // 检查是否正在记录
    int GetInterval() const { return interval_seconds_; }  // 获取记录间隔
    const std::string& GetInitializedFilename() const { return initialized_filename_; }  // 获取文件名
    
    // 新增的初始化方法，在系统启动时调用
    bool InitializeSensorDataLogging();  // 初始化传感器日志记录系统
    #endif

private:
    uint8_t calcCRC8(const uint8_t* data, uint8_t len);
    
    // 简化的成员变量 - 只使用一个文件目录
    esp_timer_handle_t timer_ = nullptr;
    std::string log_path_ = "/sdcard/scd4x";  // 单一目录路径
    int interval_seconds_ = 0;
    bool is_logging_ = false;
    std::string initialized_filename_;  // 初始化时创建的文件名
    
    // 简化的辅助函数
    // static void TimerCallback(void* arg);
    // bool InitializeDirectories();  // 初始化目录
    // bool InitializeCSVFile();  // 初始化CSV文件头
    // bool SaveCurrentDataToFile();  // 实际保存数据到文件
    // std::string GenerateTimestampLogFilename();  // 生成带时间戳的文件名
    // bool CreateAndVerifyDirectory(const std::string& path); // 创建并验证单个目录
};